#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# 函数可以作为返回值(闭包)
def cals_sum1(*args):
    sum = 0
    for arg in args:
        sum += arg
    return sum


# 闭包
def cals_sum2(*args):
    def sum():
        _sum = 0
        for arg in args:
            _sum += arg
        return _sum

    return sum


f = cals_sum2(1, 2, 3)
print(f())  # 6


# 返回闭包时：返回函数不要引用任何循环变量，或者后续会发生变化的变量。
def count():
    fs = []
    for i in range(1, 4):
        def f():
            return i * i

        fs.append(f)
    return fs


f1, f2, f3 = count()
print(f1(), f2(), f3())  # 9 9 9


# 解决方案：
# 方法是再创建一个函数，用该函数的参数绑定循环变量当前的值，
# 无论该循环变量后续如何更改，已绑定到函数参数的值不变：
def count2():
    def f(j):
        def g():
            return j * j

        return g

    fs = []
    for i in range(1, 4):
        fs.append(f(i))
    return fs


f4, f5, f6 = count2()
print(f4(), f5(), f6())  # 1 4 9


# 案例：
def createCounter():
    i = 0
    def count(i):
        i += 1
        return i
    return count


# 测试:
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA())  # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
    print('测试通过!')
else:
    print('测试失败!')
